/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.epsi.blokus;

import org.epsi.blokus.joueur.Client;
import org.epsi.blokus.joueur.Opponent;
import org.epsi.blokus.joueur.Player;
import org.epsi.blokus.joueur.TrainingClient;
import org.epsi.blokus.joueur.TrainingOpponent;
import org.epsi.blokus.tools.IConstantes;
import org.epsi.blokus.tools.Log;

/**
 *
 * @author julien.lafont
 */
public class LocalGame implements Runnable, IConstantes {

    private Client client;
    private Opponent opponent;
    private Player winner = null;

    public static enum T_ETAT_PARTIE { ON, OFF };
    private T_ETAT_PARTIE etat;
    
    public LocalGame(Client client, Opponent opponent) {
        this.client = client;
        this.opponent = opponent;
        this.etat = T_ETAT_PARTIE.ON;

    }

    public void run() {

        Log.out("LocalGame : Lancement");
        
       
        try {

            // On attend que le joueur humain soit pret
            this.client.getSemInitialisationJoueur().acquire();

            Log.out("LocalGame : Le joueur humain est prêt");

            Player joueurs[] = { this.client, this.opponent };
            int indexCoup = 0;

            while (this.etat != T_ETAT_PARTIE.OFF)
            {

                Player joueur = joueurs[indexCoup%2];
                Log.out("LocalGame : Nouveau tour : "+joueur.getPseudo());

                // Le joueur peut jouer
                joueur.notifierTourDeJeu();

                Log.out("LocalGame : En attente du coup");

                // Si c'est l'ordinateur, on le fait jouer
                if (!joueur.itsMe()) ((TrainingOpponent)joueur).jouerCoupAleatoire();

                // Sinon on attend que le joueur joue
                else  joueur.getSemaphoreTourDeJeu().acquire();   // Le release se fait quand il click

                Log.out("LocalGame : Coup joué");

                // Opérations de fin de coup
                joueur.notifierFinTourDeJeu();

                // Vérification du temps restant
                if (joueur.isTimeOut())
                {
                    // Le joueur en timeout perd
                    joueur.changeBehaviorLoose();

                    // L'adversaire gagne
                    winner = joueurs[(indexCoup+1)%2];
                    winner.changeBehaviorWin();

                    this.etat = T_ETAT_PARTIE.OFF;
                }

                // Le dernier coup était-il victorieux ?
                if (joueur.isWinner())
                {
                    winner = joueur;
                    
                    Player adversaire = joueurs[(indexCoup+1)%2];
                    adversaire.changeBehaviorLoose();

                    this.etat = T_ETAT_PARTIE.OFF;
                }

                indexCoup++; // Passe au joueur suivant

            }

        } catch (InterruptedException ex) {
            Log.out(ex.getMessage());
            this.etat = T_ETAT_PARTIE.OFF;
        }


    }

}
